package Project4;

import java.util.*;

public class Tools {

	public static String fixedPoint = "^[+-]?\\d+$";
	public static String floatPoint = "^[+-]?(\\d+)|(\\.\\d+)|(\\d+\\.\\d+)$";
	public static String operator = "[-+*/]";

	public static int evaluateFixed(String[] expression) {
		Deque<Integer> stack = new ArrayDeque<Integer>();
		String s = "";
		int o1, o2;

		for(int i = 0; i < expression.length; i++) {
			s = expression[i];
			
			if (s.matches(fixedPoint)) {
				stack.push(Integer.valueOf(s));
			}
			if (s.matches(operator) && stack.size() > 1) {
				// Reverse the operands, because non-commutativity
				o2 = stack.pop();
				o1 = stack.pop();

				//Hope that s is an operator
				if (s.equals("+")) {
					stack.push(o1 + o2);
				}
				else if (s.equals("-")) {
					stack.push(o1 - o2);
				}
				else if (s.equals("*")) {
					stack.push(o1 * o2);
				}
				else if (s.equals("/")) {
					stack.push(o1 / o2);
				}
			}
		}
		if (stack.size() == 1)
			return stack.pop();
		// Something weird happend.
		else
			return Integer.MIN_VALUE;
	}

	public static double evaluateFloat(String[] expression) {
		Deque<Double> stack = new ArrayDeque<Double>();
		String s = "";
		double o1, o2;

		for(int i = 0; i < expression.length; i++) {
			s = expression[i];
			
			if (s.matches(floatPoint)) {
				// Attempt to cast s to Double
				stack.push(Double.valueOf(s));
			}
			if (s.matches(operator) && stack.size() > 1) {
				// Reverse the operands, because non-commutativity
				o2 = stack.pop();
				o1 = stack.pop();

				//Hope that s is an operator
				if (s.equals("+")) {
					stack.push(o1 + o2);
				}
				else if (s.equals("-")) {
					stack.push(o1 - o2);
				}
				else if (s.equals("*")) {
					stack.push(o1 * o2);
				}
				else if (s.equals("/")) {
					stack.push(o1 / o2);
				}
			}
		}
		if (stack.size() == 1)
			return stack.pop();
		// Something weird happend.
		else
			return Double.NaN;
	}

	public static String[][] splitOperands(String[] exp) {

		Deque<String> queue = new ArrayDeque<String>();
		ArrayList<String[]> expList = new ArrayList<String[]>();
		int safeOp = 0;
		boolean isVariable = false;

		for (int i = 0; i < exp.length; i++) {
			if (exp[i].matches(floatPoint)) {
				queue.add(exp[i]);
			}
			else if (exp[i].matches(operator) && !isVariable) {
				queue.add(exp[i]);
				safeOp = i;
			}
			else if (exp[i].matches(operator) && isVariable){
				queue.add(exp[i]);
				isVariable = false;
				expList.add(queue.toArray(new String[0]));
				queue.clear();
			}
			else {
				queue.add(exp[i]);
				if (safeOp > 0 ){
					String[] tempExp = new String[safeOp+1];
					isVariable = true;
					for (int j = 0; j <= safeOp; j++)
						tempExp[j] = queue.poll();
					safeOp = 0;
					expList.add(tempExp);
				}
			}
		}
		if (queue.size() > 0)
			expList.add(queue.toArray(new String[0]));
		return expList.toArray(new String[0][0]);
	}
}
